package org.ncibi.cytoscape.metscape.data;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FilenameUtils;
import org.ncibi.cytoscape.metscape.file.DataFile;
import org.ncibi.cytoscape.metscape.file.ExcelFile;
import org.ncibi.cytoscape.metscape.file.TextFile;
import org.ncibi.cytoscape.metscape.utils.NumUtils;

public class GeneData {
	
	private String[] columns = new String[0];
	private Map<String, Boolean> columnIsSigned = new HashMap<String, Boolean>();
	private Map<Integer, Double[]> geneMap = new HashMap<Integer, Double[]>();
	private String name = "(none)";
	
	public static GeneData parse(File geneFile) {
		
		GeneData ret = null;
		try {
			GeneData ex = new GeneData();
			DataFile base;
			if(geneFile.getName().endsWith(".xls") || geneFile.getName().endsWith(".xlsx") )
				base = new ExcelFile(geneFile);
			else
				base = new TextFile(geneFile);
			ex.name = FilenameUtils.removeExtension(geneFile.getName());
			int startRow = base.getStartRowIndex();
			int endRow = base.getEndRowIndex();
			int endCol = 0;
			for(int i=1; i<=base.getEndColIndex(0); i++) {
				if(base.getString(0, i) == null) break;
				endCol++;
			}
			if (endCol > 0) {
				ex.columns = new String[endCol];
				for (int col = 1; col <= endCol; col++){
					String s = base.getString(0, col);
					ex.columns[col - 1] = s.trim();
					ex.columnIsSigned.put(s.trim(), false);
				}
			}
			startRow ++;
			for (int row = startRow; row < (endRow + 1); row++){
				Integer geneId = base.getInteger(row, 0);
				if (geneId == null) continue;
				Double[] data = new Double[endCol];
				for (int col = 1; col <= endCol; col++){
					data[col-1] = base.getDouble(row, col);
					if(data[col-1] != null && data[col-1] < 0) {
						ex.columnIsSigned.put(ex.columns[col-1], true);
					}
				}
				ex.addRecord(geneId, data);
			}
			ret = ex;
		} catch (Throwable t) {
			t.printStackTrace();
		}
		return ret;
	}
	
	public static GeneData parse(String geneString) {
		GeneData ret = null;
		try {
			GeneData ex = new GeneData();
			List<Integer> genes = NumUtils.toIntegerList(geneString);
			if(genes == null) throw new Exception();
			for(Integer geneId: genes) {
				ex.addRecord(geneId,null);
			}
			ret = ex;
		} catch (Throwable t) {
			t.printStackTrace();
		}
		return ret;
	}

	private void addRecord(Integer geneId, Double[] data) {
		geneMap.put(geneId,data);
	}

	public Double[] getData(Integer geneId) {
		return geneMap.get(geneId);
	}
	
	public String[] getColumns(){
		return columns;
	}
	
	public void setColumns(String[] columns) {
		this.columns = columns;
	}
	
	public Map<String, Boolean> getColumnIsSigned() {
		return columnIsSigned;
	}

	public void setColumnIsSigned(Map<String, Boolean> columnIsSigned) {
		this.columnIsSigned = columnIsSigned;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public Map<Integer, Double[]> getGeneMap() {
		return geneMap;
	}

	public void setGeneMap(Map<Integer, Double[]> geneMap) {
		this.geneMap = geneMap;
	}
	
	public Set<Integer> idSet(){
		return geneMap.keySet();
	}
	
	public boolean isEmpty(){
		if(geneMap.isEmpty())
			return true;
		else
			return false;
	}
	
	public boolean equals(Object o) {
		if(o instanceof GeneData)
		{
			GeneData other = (GeneData) o;
			if(Arrays.equals(columns,other.getColumns())
					&& geneMap.equals(other.getGeneMap()) 
					&& name.equals(other.getName()))
				return true;
		}
		return false;
	}
	
	public String toString() {
		return name;
	}

}
